/**
 * ProActions 合并ElButton为下拉菜单
 *
 * 属性：
 * limit: number // 表示带更多按钮一共展示多个
 * dropProps：object // ElDropdown 的属性
 *
 * items: {
 *  ...button的所有属性，
 * content: 文案
 * }
 *
 * slot:
 * content: 会渲染为 ElDropdown 的default，最好存在根标签；不存在时，会有默认补位内容；
 * default: 只允许ElButton，会根据limit将需要的部分渲染为 ElDropMenuItem，
 *
 */

import {
  ElButton,
  ElDropdown,
  ElDropdownItem,
  ElDropdownMenu,
  ElSpace,
} from "element-plus";
import { VNode, computed, defineComponent, h } from "vue";
import Icon from "@/components/Icon.vue";
import { getSlotNode } from "@/utils";

import type { ButtonProps, DropdownInstance } from "element-plus";

export type TProActionItem = {
  content: string;
} & ButtonProps;

export type TProButtonProps = {
  text?: boolean;
  size?: "small" | "large";
  offset?: number | [number, number]; // 即ElSpace的size属性

  limit?: number;
  dropProps?: DropdownInstance["$props"];
  items?: TProActionItem[];

  // dropdown按钮文案
  buttonText?: string;
};

export default defineComponent(
  (
    {
      limit = 3,
      items,
      dropProps,
      text,
      size,
      offset,

      buttonText = "更多操作",
    }: TProButtonProps,
    { slots, emit }
  ) => {
    // 获取Dropdown节点
    function getDropdown(list: VNode[]) {
      const items = list.map((e) =>
        h(ElDropdownItem, e.props, e.children as VNode[])
      );
      return h(
        ElDropdown,
        {
          // style: `${Math.max(limit, 1) > 1 ? "margin-left: 12px" : ""}`,
          size,
          ...dropProps,
        },
        {
          dropdown: () => h(ElDropdownMenu, null, () => items),
          // 存在 content 的slot，会作为dropmenu的 default 部分，多个标签/节点，需要有根标签，否则只会渲染第一个
          default: () =>
            slots.content ??
            h(ElButton, { text, size }, () => [
              buttonText,
              h(Icon, { name: "ArrowDown" }),
            ]),
        }
      );
    }

    const itemBtns = computed(() => {
      return (
        items?.map((item) => {
          const { content, ...rest } = item;
          return h(
            ElButton,
            {
              onClick: () => emit("actionClick", item),
              ...rest,
            },
            () => content
          );
        }) || []
      );
    });

    const btns = computed(() => {
      const slotsList = getSlotNode(slots.default, [])
        .map((e: VNode) => (e.patchFlag == 128 ? e.children : e))
        .flat()
        .filter((e: any) => e.type?.name == "ElButton");

      const list = itemBtns.value.concat(slotsList);

      // 超过限制部分，转为dropmenu形式
      const dropNode =
        list.length > Math.max(limit, 1)
          ? getDropdown(list.splice(limit - 1) as VNode[])
          : undefined;

      return [...list, dropNode];
    });

    return () => h(ElSpace, { size: offset ?? size }, btns.value);
  },
  {
    props: [
      "limit",
      "dropProps",
      "items",
      "buttonText",
      "text",
      "size",
      "offset",
    ],
    emits: ["actionClick"],
  }
);
